package org.byacko.simplemock;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Asserter {
	
	private Object assertObject;
	private Method assertMethod;

	protected Asserter(Object assertObject, String methodName, Class<?>[] argTypes)
			throws InvalidAssertionException {
		this.assertObject = assertObject;
		final Class<?> clazz = assertObject.getClass();
		try {
			this.assertMethod = clazz.getMethod(methodName, argTypes);
		} catch (SecurityException e) {
			throw new InvalidAssertionException("クラス：" + clazz.getName()
					+ "のメソッド：" + methodName + "は呼び出し不可能です。");
		} catch (NoSuchMethodException e) {
			throwMethodNotFound(clazz, methodName);
		}
	}

	public void invoke(Object[] args) throws Throwable {
		try {
			assertMethod.invoke(assertObject, args);
		} catch (IllegalArgumentException e) {
			throwAssertInvocation(e);
		} catch (IllegalAccessException e) {
			throwAssertInvocation(e);
		} catch (InvocationTargetException e) {
			throw e.getCause();
		}
	}

	private void throwAssertInvocation(Throwable t) {
		throw new AssertionInvocationException("クラス：" + assertObject.getClass().getName() + 
				"のメソッド：" + assertMethod.getName() + "を実行できません。", t);
	}

	private void throwMethodNotFound(Class<?> clazz, String methodName) {
		throw new InvalidAssertionException("クラス：" + clazz.getName() + "のメソッド："
				+ methodName + "が見つかりません。");
	}
}
